/**
 * 用于将 ast 生成 render
 */

// 匹配 {{ name }} 的正则
const defaultTagRE = /\{\{((?:.|\r?\n)+?)}}/g

// 生成 render
export function generate(el) {
  // _c() => createElement()
  // _v() => createTextNode()
  // _s() => {{ name }} => _s(name)

  const children = formatChildren(el)

  return `_c('${el.tag}', ${
    el.attrs.length
      ? `${formatProps(el.attrs)}`
      : 'undefined'
  }, ${children ? `${children}` : ''})
  `
}

function generateChild(node) {
  if (node.type === 1) {
    return generate(node)
  } else if (node.type === 3) {
    let text = node.text

    if (!defaultTagRE.test(text)) {
      return `_v(${JSON.stringify(text)})`
    }

    let match
    let index
    let lastIndex = defaultTagRE.lastIndex = 0
    const textArr = []
    while (match = defaultTagRE.exec(text)) {
      index = match.index
      if (index > lastIndex) {
        textArr.push(JSON.stringify(text.slice(lastIndex, index)))
      }
      textArr.push(`_s(${match[1].trim()})`)
      lastIndex = index + match[0].length
    }

    if (lastIndex < text.length) {
      textArr.push(JSON.stringify(text.slice(lastIndex)))
    }

    return `_v(${textArr.join('+')})`
  }
}

function formatChildren(el) {
  const children = el.children

  if (children) {
    return children.map(child => generateChild(child)).join(',')
  }

  return ''
}

// 拼接属性字符串
function formatProps(attrs) {
  let attrStr = ''

  for (let i = 0; i < attrs.length; i++) {
    let attr = attrs[i]

    if (attr.name === 'style') {
      const styleAttrs = {}
      attr.value
          .split(';')
          .filter(item => item)
          .map(styleAttr => {
            let [key, val] = styleAttr.trim().split(':')
            styleAttrs[key.trim()] = val.trim()
          })
      attr.value = styleAttrs
    }

    attrStr += `${attr.name}:${JSON.stringify(attr.value)},`
  }

  return `{${attrStr.slice(0, -1)}}`
}
